// cronometer.cpp : Defines the entry point for the application.
//

//Include in stdafx.h for pre-compiled headers
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>


//Struct for time counting
typedef struct time_counting{
	unsigned short int hundredths_of_second;
	unsigned short int tenths_of_second;
	unsigned short int u_seconds;
	unsigned short int d_seconds;
	unsigned short int u_minutes;
	unsigned short int d_minutes;
	unsigned short int u_hours;
	unsigned short int d_hours;
	unsigned int days;
} time_counting;
//For buttons
enum{ID_START_BUTTON = 500, ID_STOP_BUTTON, ID_SPLIT_BUTTON, ID_RESET_BUTTON};

enum{TIMER1 = 1};


#define MAX_LOADSTRING 100
#define SCREEN_WIDTH 200
#define SCREEN_HEIGhT 160

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING] = TEXT("Cronometer");					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING] = TEXT("CRONOMETER");			// the main window class name
//Buttons
TCHAR szStartButton[MAX_LOADSTRING];

HWND hWnd;
//Four buttons
HWND hStartButton;
HWND hStopButton;
HWND hSplitButton;
HWND hResetButton;

//Actual time counting
time_counting time;
//Splited time simple version for now
time_counting splited_time;
bool is_splited;
bool is_started;

// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

void reset_cronometer(){
	time.hundredths_of_second = 0;
	time.tenths_of_second = 0;
	time.u_seconds = 0;
	time.d_seconds = 0;
	time.u_minutes = 0;
	time.d_minutes = 0;
	time.u_hours = 0;
	time.d_hours = 0;
	time.days = 0;
	is_splited = false;
	is_started = false;
}

void increment_cronometer(){
	time.hundredths_of_second += 1;
	if(time.hundredths_of_second > 9){
		time.hundredths_of_second = 0;
		time.tenths_of_second += 1;
		if(time.tenths_of_second > 9){
			time.tenths_of_second = 0;
			time.u_seconds += 1;
			if(time.u_seconds > 9){
				time.u_seconds = 0;
				time.d_seconds++;
				if(time.d_seconds > 5){
					time.d_seconds = 0;
					time.u_minutes++;
					if(time.u_minutes > 9){
						time.u_minutes = 0;
						time.d_minutes++;
						if(time.d_minutes > 5){
							time.d_minutes = 0;
							time.u_hours++;
							if(time.u_hours > 9 && time.d_hours < 2){
								time.u_hours = 0;
								time.d_hours++;
							}
							else if(time.u_hours > 4 && time.d_hours == 2){
								time.d_hours = 0;
								time.u_hours = 0;
								time.days++;
							}
						}
					}
				}
			}
		}
	}
}

wchar_t* generate_wchar_from_timer(wchar_t* p_char, time_counting* tc, int s){
	_itow_s(tc->days, p_char, s, 10);
	wcscat_s(p_char, s, TEXT("d"));
	wchar_t *temp = new wchar_t[s];
	_itow_s(tc->d_hours, temp, s, 10);
	wcscat_s(p_char, s, temp);
	_itow_s(tc->u_hours, temp, s, 10);
	wcscat_s(p_char, s, temp);
	wcscat_s(p_char, s, TEXT(":"));
	_itow_s(tc->d_minutes, temp, s, 10);
	wcscat_s(p_char, s, temp);
	_itow_s(tc->u_minutes, temp, s, 10);
	wcscat_s(p_char, s, temp);
	wcscat_s(p_char, s, TEXT(":"));
	_itow_s(tc->d_seconds, temp, s, 10);
	wcscat_s(p_char, s, temp);
	_itow_s(tc->u_seconds, temp, s, 10);
	wcscat_s(p_char, s, temp);
	wcscat_s(p_char, s, TEXT(":"));
	_itow_s(tc->tenths_of_second, temp, s, 10);
	wcscat_s(p_char, s, temp);
	_itow_s(tc->hundredths_of_second, temp, s, 10);
	wcscat_s(p_char, s, temp);
	if(temp) delete[] temp;
	return p_char;
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;

	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
	}

	return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= 0;  //Default Icon
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= 0;  //No menu
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= 0;

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, 
	   /*WS_OVERLAPPEDWINDOW*/WS_CAPTION | WS_SYSMENU,
	   CW_USEDEFAULT, 0, SCREEN_WIDTH, SCREEN_HEIGhT, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application buttons
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	RECT rect;

	switch (message)
	{
	case WM_CREATE:
		hStartButton = CreateWindow(TEXT("Button"),TEXT("Start"),
			BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
			5, 5, 50, 25, hWnd, (HMENU)ID_START_BUTTON,
			hInst, 0);
		
		hStopButton = CreateWindow(TEXT("Button"),TEXT("Stop"),
			BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
			5, 35, 50, 25, hWnd, (HMENU)ID_STOP_BUTTON,
			hInst, 0);

		hSplitButton = CreateWindow(TEXT("Button"),TEXT("Split"),
			BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
			5, 65, 50, 25, hWnd, (HMENU)ID_SPLIT_BUTTON,
			hInst, 0);

		hResetButton = CreateWindow(TEXT("Button"),TEXT("Reset"),
			BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
			5, 95, 50, 25, hWnd, (HMENU)ID_RESET_BUTTON,
			hInst, 0);
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		if(!is_splited){
			wchar_t print_text[MAX_LOADSTRING];
			generate_wchar_from_timer(print_text, &time, MAX_LOADSTRING);

			RECT rectangle_area;
			rectangle_area.left = 70;
			rectangle_area.top = 55;
			rectangle_area.bottom = 70;
			rectangle_area.right = 175;
			DrawText(hdc, print_text, -1, &rectangle_area, 
				DT_LEFT);
		}
		else{
			wchar_t print_text[MAX_LOADSTRING];
			generate_wchar_from_timer(print_text, &splited_time, MAX_LOADSTRING);

			RECT rectangle_area;
			rectangle_area.left = 70;
			rectangle_area.top = 55;
			rectangle_area.bottom = 70;
			rectangle_area.right = 175;
			DrawText(hdc, print_text, -1, &rectangle_area, 
				DT_LEFT);
		}
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_COMMAND:
		wmId = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		switch(wmId){
			case ID_START_BUTTON:
				SetTimer(hWnd,TIMER1,10,NULL);
				is_started = true;
				break;
			case ID_STOP_BUTTON:
				KillTimer(hWnd, TIMER1);
				rect.left = 70;
				rect.top = 55;
				rect.bottom = 103;
				rect.right = 175;
				InvalidateRect(hWnd, &rect, true);
				UpdateWindow(hWnd);
				is_started = false;
				break;
			case ID_SPLIT_BUTTON:
				if(is_started){
					if(is_splited){
						is_splited = false;
					}
					else{
						is_splited = true;
						splited_time.d_hours = time.d_hours;
						splited_time.d_minutes = time.d_minutes;
						splited_time.d_seconds = time.d_seconds;
						splited_time.days = time.days;
						splited_time.hundredths_of_second = time.hundredths_of_second;
						splited_time.tenths_of_second = time.tenths_of_second;
						splited_time.u_hours = time.u_hours;
						splited_time.u_minutes = time.u_minutes;
						splited_time.u_seconds = time.u_seconds;
					}
				}
				else if(is_splited){
					is_splited = false;
					rect.left = 70;
					rect.top = 55;
					rect.bottom = 103;
					rect.right = 175;
					InvalidateRect(hWnd, &rect, true);
					UpdateWindow(hWnd);
				}
				break;
			case ID_RESET_BUTTON:
				if(!is_started){
					is_splited = false;
					reset_cronometer();
					//RECT rect;
					rect.left = 70;
					rect.top = 55;
					rect.bottom = 103;
					rect.right = 175;
					InvalidateRect(hWnd, &rect, true);
					UpdateWindow(hWnd);
				}
				break;
			default:;
		}
		break;
	case WM_TIMER:
		increment_cronometer();
		if(!is_splited){
		RECT rect;
			rect.left = 70;
			rect.top = 55;
			rect.bottom = 103;
			rect.right = 175;
			InvalidateRect(hWnd, &rect, is_splited);
			//InvalidateRgn(hWnd, NULL, true);
			UpdateWindow(hWnd);
		}
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

